﻿namespace EFS.RC.CCC.Application.EndPoints.Models
{
	/// <summary>
	/// Agent role of end point
	/// </summary>
	internal class Agent : EFS.RC.CCC.Application.EndPoints.EndPoint
	{
		// Presences Operators : Agents / Supervisors
		EFS.RC.CCC.Presences.Operators.Team operatorsTeam = null;

		/// <summary>
		/// Constructor
		/// </summary>
		/// <param name="ownerUri"></param>
		public Agent(Microsoft.Rtc.Collaboration.ApplicationEndpointSettings applicationEndpointSettings)
			: base(applicationEndpointSettings)
		{
			// check
			EFS.Common.Verify.Reference(applicationEndpointSettings, "applicationEndpointSettings");

			// update settings
			applicationEndpointSettings.AutomaticPresencePublicationEnabled = true;
			applicationEndpointSettings.Presence.PreferredServiceCapabilities = null;
			applicationEndpointSettings.UseRegistration = true;
			applicationEndpointSettings.SupportedMimePartContentTypes = 
				new System.Collections.Generic.List<System.Net.Mime.ContentType>() { new System.Net.Mime.ContentType("application/octet-stream") };

			// subscribe to events
			OnPreEndPointStartup += SetupEndPointRole;
			OnEndPointActive += StartupTeam;
			OnPreEndPointShutDown += Cleanup;
		}

		#region Initalization and startup

		/// <summary>
		/// Operators team
		/// </summary>
		public EFS.RC.CCC.Presences.Operators.Team OperatorsTeam
		{
			get { return operatorsTeam; }
		}

		/// <summary>
		/// Setup the end point for agent role
		/// </summary>
		private void SetupEndPointRole(Microsoft.Rtc.Collaboration.ApplicationEndpoint applicationEndpoint)
		{
			// log
			EFS.EventLog.Log.LogInfo("EFS.RC.CCC.Application.EndPoints.Models:SetupEndPointRole", this);

			// register for calls
			applicationEndpoint.RegisterForIncomingCall<Microsoft.Rtc.Collaboration.InstantMessagingCall>(OnIncomingInstantMessagingCalls);
		}

		/// <summary>
		/// End point is now active, register agents
		/// </summary>
		/// <param name="applicationEndpoint"></param>
		private void StartupTeam(Microsoft.Rtc.Collaboration.ApplicationEndpoint applicationEndpoint)
		{
			// log
			EFS.EventLog.Log.LogInfo("EFS.RC.CCC.Application.EndPoints.Models:StartupTeam", this);

			// make local list of agents
			operatorsTeam =
				new Presences.Operators.Team(
					new EFS.RC.CCC.Deployment.Entities.Team() { ID=2, Name="Claims", EndPointID=1, Priority=0 },
					this);

			// start
			operatorsTeam.BeginStartup();
		}

		#endregion

		#region Runtime

		/// <summary>
		/// Incomming messages
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="args"></param>
		private void OnIncomingInstantMessagingCalls(object sender, Microsoft.Rtc.Collaboration.CallReceivedEventArgs<Microsoft.Rtc.Collaboration.InstantMessagingCall> args)
		{
			// log
			EFS.EventLog.Log.LogInfo("EFS.RC.CCC.Application.EndPoints.Models:OnIncomingInstantMessagingCalls", this);

			// get supervisor
			EFS.RC.CCC.Presences.Presence presence = operatorsTeam.GetPresence(args.RemoteParticipant.Uri);

			// check toast mesage
			if (args.ToastMessage.Message == "GET ME IN")
			{
				// check if in this team
				if (null != presence)
				{
					// must be supervisor
					if (presence is EFS.RC.CCC.Presences.Operators.Supervisor)
					{
						// make session
						EFS.RC.CCC.Sessions.Supervisor supervisorSession = new Sessions.Supervisor(presence as EFS.RC.CCC.Presences.Operators.Supervisor, args.Call, operatorsTeam);

						// begin startup
						supervisorSession.BeginStartup();
					}
					else
					{
						args.Call.Decline();
					}
				}
				else
				{
					args.Call.Decline();
				}
			}
		}

		#endregion

		#region Cleanup

		/// <summary>
		/// Clean-up 
		/// </summary>
		/// <param name="applicationEndpoint"></param>
		private void Cleanup(Microsoft.Rtc.Collaboration.ApplicationEndpoint applicationEndpoint)
		{
			// log
			EFS.EventLog.Log.LogInfo("Cleanup", this);

			// shut down
			EFS.RC.Common.AsyncProcess ap = operatorsTeam.BeginShutdown();

			// wait
			ap.WaitComplete();
		}

		#endregion
	}
}
